package dj.common.support;

import cn.hutool.core.util.StrUtil;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.FileCopyUtils;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;


@Slf4j
public class HttpRequestWrapper extends HttpServletRequestWrapper {

    @Getter
    @Setter
    private String body;

    private String traceId;

    public HttpRequestWrapper(HttpServletRequest request) {
        super(request);
        try {
            body = FileCopyUtils.copyToString(request.getReader());
        } catch (IOException e) {
            log.error("inputStream 获取异常");
        }
    }

    public HttpRequestWrapper(HttpServletRequest request, String traceId) {
        super(request);
        try {
            this.body = FileCopyUtils.copyToString(request.getReader());
        } catch (IOException e) {
            log.error("inputStream 获取异常");
        }
        this.traceId = traceId;
        if (StrUtil.isNotBlank(this.traceId)) {
            request.setAttribute("traceId", this.traceId);
        }
    }

    @Override
    public ServletInputStream getInputStream() {
        InputStream inputStream = new ByteArrayInputStream(body.getBytes());
        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener listener) {
            }

            @Override
            public int read() throws IOException {
                return inputStream.read();
            }
        };
    }

    @Override
    public BufferedReader getReader() {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    public String getTraceId() {
        return traceId;
    }

    public void setTraceId(String traceId) {
        this.traceId = traceId;
    }
}
